#include <iostream>
#include "exercise/50queue.hpp"

// 初始化成员列表的方法

// 接口中的内容Queue类,请到Learning/exercise/queue.hpp

// 假设有这样的一个类

// class Queue
// {
// private:
// // class scope definitions
//
//     struct Node { Item item; struct Node * next;};
//     // 这里用到了一个C++的特性: 在类中嵌套结构或者类声明, 通过将Node声明嵌套在Queue中,可以使其作用域为整个类,
//     // 也就是说: Node是这样一种类型: 可以用它声明类成员,也可以将它作为方法中的类型名称,但是只能在类中使用
//     //  private限定为这个类,只能通过本类使用被声明的类型,public可以通过作用域解析运算符::使用(比如说 Queue::Node)
//
//     enum {Q_SIZE = 10};
// // private class members
//     Node * front;       // pointer to front of Queue
//     Node * rear;        // pointer to rear of Queue
//     int items;          // current number of items in Queue
//     const int qsize;    // maximum number of items in Queue
//     // preemptive definitions to prevent public copying
//     Queue(const Queue & q) : qsize(0) { }
//     Queue & operator=(const Queue & q) { return *this;}
// public:
//     Queue(int qs = Q_SIZE); // create queue with a qs limit
//     ~Queue();
//     bool isempty() const;
//     bool isfull() const;
//     int queuecount() const;
//     bool enqueue(const Item &item); // add item to end
//     bool dequeue(Item &item);       // remove item from front
// };

// 在上面的类声明中有这样的一句话
//     const int qsize;
// 问题在于qzise是常量,所以可以进行初始化,但是不能给他赋值(因为在执行到{}之前已经创建了对象,{}内的只是重新赋值了而已,然而已经初始化的const不允许修改)
// 调用下面的构造函数将会出现问题:
// Queue::Queue(int qs){
//     qsize = qs;
// }
// 所以C++提供了一种新的方法,即初始化成员列表的方法
// 通常如下面的代码

// qsize,front,rear,items分别为这个类的数据成员
Queue::Queue(int qs) : qsize(qs), front(nullptr), rear(nullptr), items(0)
{
}
// 重要!!!!!    只有构造函数可以使用这样的写法!!!对于const的成员,还有被声明为引用的类成员,!必须!使用这样的语法初始化!!!


// 声明为引用的类成员示例
class Agency {};
class Agent{
    private:
        Agency & belong;
    public:
    Agent(Agency & a);
};

Agent::Agent(Agency & a) : belong(a)
{
}


// 如果Classy是一个类,而mem1,mem2,mem3都是这个类的数据成员,那么构造函数可以使用这样的方法初始化数据成员
// Classy::Classy(int n1, double n2,float n3) : mem1(n1),mem2(n2), mem3(n1 * n2 + 20){
// }
// 从概念上说,这些初始化工作在对象创建的时候完成,此时没有执行大括号中的任何代码

// 总结:  1. 这种格式只适用于构造函数
//        2. 必须使用这种格式来初始化非静态const成员(至少在C++11以前是这样的)
//        3. 必须使用这种格式初始化引用类型数据成员


// class Test{
// public:
//     Test():a(0){}
//     enum {size1=100,size2=200};
// private:
//     const int a;//只能在构造函数初始化列表中初始化
//     static int b;//在类的实现文件中定义并初始化
//     const static int c;//与 static const int c;相同。
// };

// int Test::b=0;       //static成员变量不能在构造函数初始化列表中初始化，因为它不属于某个对象。
// cosnt intTest::c=0;  //注意：给静态成员变量赋值时，不需要加static修饰符，但要加cosnt。



//          C++11中的类内初始化
// 在C++11中允许你使用更加直观的方式进行初始化
class Classy{
    int mem1 = 10;
    const int mem2 = 20;
};
// 上面的代码和在构造函数中使用成员初始化列表等价
// Classy::Classy(int n1,int n2) : mem1(10),mem2(20) { }
// 成员mem1和mem2分别被初始化成10和20

// 如果使用下面的配合C++11的类内初始化
// Classy::Classy(int n1) : mem1(10) { }
// mem1将初始化为10,mem2为类中声明的保持默认的20
